package com.pokermind.dse.tcp.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pokermind.dse.tcp.protocol.ProtocolConstants;
import com.pokermind.dse.tcp.protocol.ProtocolMessage;
import com.pokermind.dse.tcp.util.ResponseWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import jakarta.annotation.PostConstruct;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.RuntimeMXBean;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * System Service
 * 系统服务，处理TCP协议的系统级消息
 * 
 * 支持的协议：
 * - HEARTBEAT_REQ (9001) - 心跳请求
 * - AUTH_REQ (9002) - 认证请求
 * - SERVER_STATUS_REQ (9003) - 服务器状态请求
 * 
 * 特点：
 * - 轻量级操作，同步处理
 * - 不依赖外部服务
 * - 快速响应
 * 
 * @author PokerMind Team
 */
@Service
public class SystemService {

    private static final Logger logger = LoggerFactory.getLogger(SystemService.class);

    private final ObjectMapper objectMapper = new ObjectMapper();
    
    @Autowired
    private com.pokermind.dse.tcp.handler.ConnectionHandler connectionHandler;
    
    @Autowired
    private AuthService authService;
    
    // 系统信息
    private final RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
    private final MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
    private final long startTime = System.currentTimeMillis();
    private final String serverVersion = "1.0.0"; // TODO: 从配置或构建信息获取

    @PostConstruct
    public void initialize() {
        logger.info("SystemService initialized");
    }

    /**
     * 处理系统协议消息
     */
    public ProtocolMessage processMessage(ProtocolMessage message) {
        short protocolId = message.getProtocolId();
        
        // 设置请求上下文信息用于日志追踪
        setupRequestContext(message);
        
        if (logger.isDebugEnabled()) {
            logger.debug("Processing system message: {} from {}", 
                    message.getProtocolName(), message.getClientId());
        }

        try {
            switch (protocolId) {
                case ProtocolConstants.HEARTBEAT_REQ:
                    return handleHeartbeat(message);
                case ProtocolConstants.AUTH_REQ:
                    return handleAuth(message);
                case ProtocolConstants.SERVER_STATUS_REQ:
                    return handleServerStatus(message);
                default:
                    logger.warn("Unsupported system protocol: {} from {}", 
                            message.getProtocolName(), message.getClientId());
                    return ResponseWrapper.createErrorResponse(message, 4001, "unsupported_protocol");
            }
        } catch (Exception e) {
            logger.error("Error processing system message {}: {}", 
                    message.getProtocolName(), e.getMessage(), e);
            return ProtocolMessage.createBusinessErrorResponse(message, 
                    "System processing error", e.getMessage());
        } finally {
            // 清理请求上下文
            com.pokermind.common.context.RequestContext.clear();
        }
    }
    
    /**
     * 设置请求上下文信息
     */
    private void setupRequestContext(ProtocolMessage message) {
        try {
            // 提取客户端RequestId
            String requestId = ResponseWrapper.extractClientRequestId(message);
            if (requestId != null) {
                com.pokermind.common.context.RequestContext.setRequestId(requestId);
            }
            
            // 设置连接ID - 优先使用客户端发送的connId
            String connectionId = extractClientConnectionId(message);
            if (connectionId == null) {
                // 如果客户端没有发送connId，使用默认的网络连接标识
                connectionId = message.getClientId();
            }
            if (connectionId != null) {
                com.pokermind.common.context.RequestContext.setConnectionId(connectionId);
            }
            
            // V4.7: 设置请求内容（不格式化，保持单行）
            String requestContent = message.getJsonBody();
            if (requestContent != null) {
                com.pokermind.common.context.RequestContext.setRequestContent(requestContent);
            }
            
        } catch (Exception e) {
            // 如果提取失败，记录警告但不影响业务处理
            logger.warn("Failed to setup request context from message: {}", e.getMessage());
        }
    }
    
    /**
     * 从请求消息中提取客户端连接ID
     */
    private String extractClientConnectionId(ProtocolMessage message) {
        try {
            if (message.getJsonNode() != null && message.getJsonNode().has("connId")) {
                return message.getJsonNode().get("connId").asText();
            } else if (message.getJsonBody() != null) {
                JsonNode jsonNode = objectMapper.readTree(message.getJsonBody());
                if (jsonNode.has("connId")) {
                    return jsonNode.get("connId").asText();
                }
            }
        } catch (Exception e) {
            // 忽略解析错误
        }
        return null;
    }

    /**
     * 处理心跳请求
     */
    private ProtocolMessage handleHeartbeat(ProtocolMessage message) throws Exception {
        // 使用新的请求格式，手动提取业务数据
        JsonNode requestNode = objectMapper.readTree(message.getJsonBody());
        if (!requestNode.has("data")) {
            throw new IllegalArgumentException("Request missing 'data' field");
        }
        JsonNode businessData = requestNode.get("data");
        
        long clientTimestamp = businessData.has("timestamp") ? businessData.get("timestamp").asLong() : 0;
        String clientId = businessData.has("client_id") ? businessData.get("client_id").asText() : "unknown";
        
        long serverTime = System.currentTimeMillis();
        
        if (logger.isTraceEnabled()) {
            logger.trace("Heartbeat from {}: client_time={}, server_time={}", 
                    clientId, clientTimestamp, serverTime);
        }
        
        // 心跳检测响应的data为空，仅确认连接可用
        return ResponseWrapper.createSuccessResponse(message, "heartbeat", null);
    }

    /**
     * 处理认证请求 - 使用API Key认证
     */
    private ProtocolMessage handleAuth(ProtocolMessage message) throws Exception {
        // 委托给AuthService处理
        return authService.handleAuth(message);
    }

    /**
     * 处理服务器状态请求
     */
    private ProtocolMessage handleServerStatus(ProtocolMessage message) throws Exception {
        // 使用新的请求格式，手动提取业务数据
        JsonNode requestNode = objectMapper.readTree(message.getJsonBody());
        if (!requestNode.has("data")) {
            throw new IllegalArgumentException("Request missing 'data' field");
        }
        JsonNode businessData = requestNode.get("data");
        String clientId = businessData.has("client_id") ? businessData.get("client_id").asText() : "unknown";
        
        // 获取系统状态信息
        long uptime = (System.currentTimeMillis() - startTime) / 1000; // 秒
        double memoryUsage = getMemoryUsage();
        double cpuUsage = getCpuUsage();
        com.pokermind.dse.tcp.handler.ConnectionHandler.ConnectionStats connStats = connectionHandler.getConnectionStats();
        boolean healthy = memoryUsage < 0.9 && cpuUsage < 0.8; // 简单的健康检查
        
        // 构建详细的状态响应，包含连接统计信息
        java.util.Map<String, Object> statusData = new java.util.LinkedHashMap<>();
        statusData.put("server_version", serverVersion);
        statusData.put("uptime_seconds", uptime);
        statusData.put("cpu_usage", cpuUsage);
        statusData.put("memory_usage", memoryUsage);
        statusData.put("healthy", healthy);
        
        // 将连接统计信息转换为Map格式
        java.util.Map<String, Object> connectionData = new java.util.LinkedHashMap<>();
        connectionData.put("current_connections", connStats.getCurrentConnections());
        connectionData.put("max_connections", connStats.getMaxConnections());
        connectionData.put("connections_accepted", connStats.getTotalAccepted());
        connectionData.put("connections_rejected", connStats.getTotalRejected());
        connectionData.put("connections_closed", connStats.getTotalClosed());
        connectionData.put("idle_timeouts", connStats.getTotalIdleTimeouts());
        double connectionUsage = connStats.getMaxConnections() > 0 ? 
            (double) connStats.getCurrentConnections() / connStats.getMaxConnections() * 100.0 : 0.0;
        connectionData.put("usage_percentage", connectionUsage);
        
        statusData.put("connections", connectionData);
        
        String responseJson = objectMapper.writeValueAsString(statusData);
        
        if (logger.isDebugEnabled()) {
            logger.debug("Server status requested by {}: uptime={}s, memory={}%, cpu={}%", 
                    clientId, uptime, (int)(memoryUsage * 100), (int)(cpuUsage * 100));
        }
        
        return ProtocolMessage.createResponse(message, responseJson);
    }

    /**
     * 生成会话ID
     */
    private String generateSessionId(String userId) {
        return userId + "_" + System.currentTimeMillis() + "_" + 
               Integer.toHexString(java.util.concurrent.ThreadLocalRandom.current().nextInt());
    }

    /**
     * 获取内存使用率
     */
    private double getMemoryUsage() {
        try {
            long used = memoryBean.getHeapMemoryUsage().getUsed();
            long max = memoryBean.getHeapMemoryUsage().getMax();
            return max > 0 ? (double) used / max : 0.0;
        } catch (Exception e) {
            return 0.0;
        }
    }

    /**
     * 获取CPU使用率（简化版本）
     */
    private double getCpuUsage() {
        try {
            // 这里返回一个估算值，实际项目中可以使用更精确的方法
            com.sun.management.OperatingSystemMXBean osBean = 
                    (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
            double cpuUsage = osBean.getProcessCpuLoad();
            return cpuUsage >= 0 ? cpuUsage : 0.0;
        } catch (Exception e) {
            return 0.0;
        }
    }

    /**
     * 获取活跃连接数（TODO: 集成ConnectionHandler）
     */
    private int getActiveConnectionsCount() {
        // TODO: 从ConnectionHandler或其他组件获取实际连接数
        return 0;
    }
}
